CLB/ALB の障害調査依頼を受けた時に確認していること
記事を書こうと思ったきっかけ
サポートへの問い合わせが EC2 に次いで多いのが "CLB/ALB の障害調査依頼" だから
CLB/ALB の障害調査依頼では「アクセスが遅延していた」もしくは「50X エラーが発生していた」ので調査して欲しい旨のお問い合わせをいただくことが多いです。特徴としては、それが CLB/ALB の問題なのか EC2 などバックエンドの問題なのかが切り分けされていない場合が多くみられます。どちらが原因か両方を追う必要があるため確認する項目は多いですが、CLB/ALB 側のいくつかの CloudWatch メトリクスを確認することで CLB/ALB かバックエンドの問題かの切り分けは概ね可能だと思います。
もちろん CLB/ALB はマネージドサービスであるため最終的には AWS への確認が必要になる場合もありますが、自分である程度原因を切り分けてから問い合わせを行うことで、結果的に早く障害原因にたどり着けると思い書きました。
前提
- CLB/ALB を想定して書いています、NLB は対象外です
- AWS マネジメントコンソールから確認できる範囲でという前提で書いています
確認すること
1. UnHealthyHostCount が増えていないかを確認
Amazon CloudWatch から UnHealthyHostCount メトリクスを確認します。
このメトリクスはロードバランサーに登録された、異常なインスタンスの数を表します。どのようなインスタンスが異常なインスタンスと判断されるかというと、CLB/ALB からのヘルスチェックに対して構成された異常なしきい値を超えた場合に、異常な状態と見なされます。異常なインスタンスは CLB/ALB から切り離しが行われるため、当然切り離されたインスタンスへのアクセスはできなくなります。
確認すること
ヘルスチェックが失敗した原因についてバックエンドの Web サーバのアクセスログおよびエラーログ、アプリケーションのログに不審な点が無いかを確認しましょう。
また、ヘルスチェック失敗の原因としてはバックエンドからの応答遅延も考えられるため、ヘルスチェックのタイムアウト値とバックエンドからの応答遅延との突き合わせも行いましょう。 なお、ヘルスチェックの設定は環境によって異なるため、どのようなチェックになっているかを確認しましょう。
参考
- Classic Load Balancer のヘルスチェックを設定する - Classic Load Balancing
- ターゲットグループのヘルスチェック - Application Load Balancer
2. CLB/ALB, バックエンドどちらが HTTP エラーコードを返しているかを確認
例えば、クライアントから Web ブラウザでアクセスした場合に 50x エラーが発生したとします。クライアントからは CLB/ALB, バックエンドどちらがエラーコードを返したかはわかりませんが、CloudWatch のメトリクスを確認することで切り分けが行なえます。
特に HTTPCode_Backend, HTTPCode_Target はバックエンドによって生成された HTTP 応答コードの数で、これにはロードバランサーによって生成される応答コードは含まれないため、このメトリクスが増えていればバックエンドがエラーコードを返していることになり、バックエンドが原因である可能性が高くなります。
確認する項目
下記 CloudWatch メトリクスの統計は必ず "合計" を選択してください。最大、最小および平均を選ぶと、すべて 1 が返されるので注意してください。
- CLB
- HTTPCode_ELB_4XX
- HTTPCode_ELB_5XX
- HTTPCode_Backend_4XX
- HTTPCode_Backend_5XX
- ALB
- HTTPCode_ELB_4XX_Count
- HTTPCode_ELB_5XX_Count
- HTTPCode_Target_4XX_Count
- HTTPCode_Target_5XX_Count
確認すること
どのメトリクスが増えていた場合は、何を確認すべきかは以下のブログ記事が非常によくまとまっているので、このブログ記事をそのまま使わせていただきます。
3. CLB/ALB とバックエンドのインスタンス間で正常に接続ができているかを確認
CLB/ALB からバックエンドへの接続エラーが増えていないかを確認します。これはヘルスチェックの失敗も含まれるため、ヘルスチェックの閾値を超えれば切り離しが発生しますが、閾値に満たない接続エラーが継続して失敗している可能性も考えられるため、このメトリクスも確認するようにしましょう。
確認する項目
下記 CloudWatch メトリクスの統計は "合計" を選択してください。最大、最小および平均はロードバランサーノードごとに報告されるため、通常有益ではありません。
- CLB
- BackendConnectionErrors
- ALB
- TargetConnectionErrorCount
確認すること
接続エラーが発生する原因として、バックエンドのインスタンスの負荷上昇により新しい接続が拒否されている可能性があります。そのため、急激なリクエスト増加やバックエンドインスタンスのリソース状況を確認するようにしましょう。
4. バックエンドからの応答遅延が発生していないかの確認
CLB/ELB がバックエンドのインスタンスにリクエストを送信した時点から、そのインスタンスが応答ヘッダーの送信を開始した時点までの合計経過時間を確認することで、バックエンドからの応答遅延が発生していないかの確認が行なえます。
確認する項目
- CLB
- Latency
- ALB
- TargetResponseTime
確認すること
バックエンドの応答遅延が発生した原因については、バックエンドの Web サーバのアクセスログおよびエラーログ、アプリケーションのログに不審な点が無いかを確認しましょう。
また、CLB/ALB のタイムアウト値によっては、バックエンドの応答を待たずに、エラーとしてクライアントにHTTP 504: Gateway Timeout を返してしまうので、その点も確認しましょう。
参考
感想
前回の EC2 の記事同様、書いてみたらむちゃくちゃ難しかった です。
書きながら私自身も学ぶことが多くあり勉強になりました。私自身も EC2 に次いで使用経験が多い CLB/ALB ですら、まだまだ知らないことが多く AWS は深いなと改めて感じました。
前回も書きましたが、障害対応の考え方は専有するよりは公開して広く知れ渡ることで、みんなが幸せになると私は考えているので、誰かのお役に立てればと公開しました。もっとこうした方がいいなど、情報があればコメントいただければと思います。
参考
- Classic Load Balancer の CloudWatch メトリクス - Elastic Load Balancing
- Application Load Balancer の CloudWatch メトリクス - Elastic Load Balancing
- Classic Load Balancer のヘルスチェックを設定する - Classic Load Balancing
- ターゲットグループのヘルスチェック - Application Load Balancer
- ELBの挙動とCloudWatchメトリクスの読み方を徹底的に理解する | Developers.IO
- [新機能] AWS Elastic Load Balancing(ELB)のタイムアウト値を変更する | Developers.IO